import copy
import os.path
import smtplib
# 负责构造文本
from email.mime.text import MIMEText
# 负责构造图片
from email.mime.image import MIMEImage
# 负责将多个对象集合起来
from email.mime.multipart import MIMEMultipart
from email.header import Header
import json
from utils import format_date
from email.utils import formataddr


class AutoEmail:
    def __init__(self, config):
        self.config_file = config
        self.config = self.read_config()
        self.mm = MIMEMultipart('related')
        self.mail_body = None
        self.mail_image = None

        self.mail_attach = None
        self.date = format_date("", "")
        self.mail_date = format_date(None, "default")

    def read_config(self):
        with open(self.config_file, "r", encoding="utf-8") as fp:
            data = json.load(fp)

        return data

    def _mails_to_str(self):
        prefix = "receiver_1_name<{}>"
        if len(self.config['mail_receivers']) == 1:
            return prefix.format(self.config['mail_receivers'][0])

        lst = [copy.deepcopy(prefix).format(it) for it in self.config['mail_receivers']]
        return ",".join(lst)

    def set_mail_head(self, subject, _from, _to):
        self.mm["From"] = formataddr(pair=(self.config['sender_name'], self.config['mail_sender']))
        # 设置接受者,注意严格遵守格式,里面邮箱为接受者邮箱
        self.mm["To"] = self._mails_to_str()
        # 设置邮件主题
        self.mm["Subject"] = Header(subject, 'utf-8')

    def set_mail_body(self, mail_body):
        # 构造文本,参数1：正文内容，参数2：文本格式，参数3：编码方式
        self.mail_body = MIMEText(mail_body, "plain", "utf-8")

    def set_mail_image(self, img: str):
        # 二进制读取图片
        image_data = open(img, 'rb')
        # 设置读取获取的二进制数据
        self.mail_image = MIMEImage(image_data.read())
        # 关闭刚才打开的文件
        image_data.close()

    def set_mail_attach(self, file: str):
        suffix = file.split(".")[-1]
        # 构造附件
        with open(file, "rb") as fp:
            self.mail_attach = MIMEText(fp.read(), 'base64', 'utf-8')
        # 设置附件信息
        attach_file_name = "new_ip_port_list_" + self.date + "." + suffix
        self.mail_attach["Content-Disposition"] = 'attachment; filename="{}"'.format(attach_file_name)

    def mail_join(self):
        self.mm.attach(self.mail_body)
        if self.mail_image is not None:
            self.mm.attach(self.mail_image)

        if self.mail_attach is not None:
            self.mm.attach(self.mail_attach)

    def send(self):
        # 设置发件人邮箱的域名和端口，端口地址
        stp = smtplib.SMTP_SSL(self.config['mail_host'], self.config['mail_port'])

        # set_debuglevel(1)可以打印出和SMTP服务器交互的所有信息
        # stp.set_debuglevel(1)
        # 登录邮箱，传递参数1：邮箱地址，参数2：邮箱授权码
        stp.login(self.config['mail_sender'], self.config['mail_license'])
        # 发送邮件，传递参数1：发件人邮箱地址，参数2：收件人邮箱地址，参数3：把邮件内容格式改为str
        stp.sendmail(self.config['mail_sender'], self.config['mail_receivers'], self.mm.as_string())
        print(format_date(None, "default") + ":" + "邮件发送成功\n")
        # 关闭SMTP对象
        stp.quit()

    def run(self):
        self.set_mail_head(self.config['subject'].format(self.mail_date), self.config['mail_sender'],
                           self.config['mail_receivers'])
        self.set_mail_body(self.config['mail_content'].format(self.mail_date))
        if self.config['image']:
            self.set_mail_image("./config/test.jpg")

        if self.config['attach']:
            file = os.path.join(self.config['path'], self.date[:-5], self.date + ".csv")
            self.set_mail_attach(file)

        self.mail_join()

        self.send()

